Operating systems and hypervisors that support execution of multiple contexts such as virtual machines (VMs) running in computer systems typically employ a page table translation hierarchy to manage mapping of memory from a virtual memory space (the memory visible to a VM) to a physical memory space (the hardware memory available on a host computer) that is divided into pages. Each page is a block of contiguous memory addresses, but page sizes may vary. When a page is mapped from an entry of a page table at the lowest level (level 1), the size of the page is the smallest size that is supported by the computer system. When a page is mapped from an entry of a page table at a higher level (level N>1), the size of the page is a larger size that is supported by the computer system. As referred to herein, “small” pages are of a smaller size than “large” pages, but small pages are not necessarily the smallest size that is supported by the computer system. Similarly, large pages are not necessarily the largest size that is supported by the computer system.
To increase memory performance, computer systems often employ a translation lookaside buffer (TLB) to cache mappings from virtual memory space to physical memory space. Since the size of the TLB is limited, computer systems may further optimize performance by using large pages in the physical memory space to back up pages in the virtual memory space to decrease the likelihood of TLB misses (i.e., mappings that are not stored in the TLB). However, if the available physical memory becomes scarce, reclaiming memory through sharing pages is made difficult. In particular, sharing large pages is typically not implemented, since the occurrence of identical large pages is usually very small and the overhead associated with identifying large pages is relatively high. Further, sharing small pages is complicated by the large page mappings, even though small pages within large pages are sharable. This unnecessarily wastes memory and leads to performance degradation.
In an attempt to reduce performance degradation, if memory becomes strained, then some hypervisors identify likely candidates for sharing at the small page granularity, break the large pages that back these small pages, and share duplicated small pages. This technique is described in U.S. patent application Ser. No. 13/935,382, entitled “Identification of Page Sharing Opportunities Within Large Pages,” the entire contents of which are incorporated by reference herein. To facilitate this sharing process, a memory sharing module (which may be located in a hypervisor) scans the virtual memory space of the VM for duplicated small virtual pages at a predetermined, fixed, page scan rate. If the memory is strained, and the small virtual page is duplicated, then the hypervisor selects the small virtual page for sharing, including breaking any large physical page that backs the small virtual page. In operation, breaking such large pages allows the hypervisor to reclaim unused or shared portions of large pages and, thus, reduce memory pressure.
However, in this strained memory state, the hypervisor also performs other reclamation operations, such as ballooning and host swapping, that consume more computer resources than identifying and breaking large pages that include duplicated small pages. If the page scan rate is relatively low compared to the percentage of large pages that back duplicated small pages, then the amount of time it takes for the small page scanning operations to reduce memory pressure may be unnecessarily long, and cause the hypervisor to employ the more expensive memory reclamation techniques. Conversely, the page scan rate may be too high if page sharing opportunities that are identified are not being exploited because memory is no longer strained.